package com.gjt.http;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

/**
 * Created with Intel IDEA.
 *
 * HttpURLConnection是 URLConnection 的抽象子类 ，一般使用URLConnection。openConnection 在强转
 *   请求方法：可以用head 只请求文档的首部。
 *   默认情况下 HttpURLConnection 会使用GET方法，可以使用setRequestMethod()改变请求方法
 *
 *   GET,POST,HEAD,PUT,DELETE,OPTIONS,TRACE
 *
 *
 *   (1):HEAD 他告诉服务器只返回http首部，不发送文件 一般用途是检查文件在最后一次缓存之后是否由修改
 *   (2):DELETE 将删除web服务器上位于指定url的文件
 *   (3):PUT 将文件放到服务器上
 *   (4):OPTIONS 询问某个特定的url支持那些选项。如果请求的url是星号（*） 那么这个请求作将作用于整个服务器而不是服务器上的某个url
 *       例如： Accept: text/html,image/gif,image/jpeg,*;q=.2;
 *   (5):TRACE 会发送http首部，服务器将从客户端接收这个首部，主要就是要看服务器和客户端之间的代理服务器做了哪些修改
 *
 *
 *
 *
 *   处理服务器响应：
 *          http服务器响应的第一行包括一个数字码和一个消息，指示做出何种响应
 *
 *   默认情况下HttpURLConnection会跟随重定向， 静态方法允许你确定是否跟随重定向
 *      public static boolean getFollowRedirects()
 *      public static void setFollowRedirects(boolean follow)
 *
 *   java 中两个方法可以针对各个实例配置重定向
 *      public boolean getInstanceFollowRedirects()
 *      public void setInstanceFollowRedirects(boolean followRedirect)
 *
 *      如果没有对给定HttpURLConnection调用setInstanceFollowRedirects()则设置默认的
 *
 *   http的流模式：Content-length字段，如果已知文件的大小可以指定。如果不知道大小可以使用分块传输编码方式。请求主体以多个部分发送。
 *      每个部分都有自己单独的长度，在url连接之前将大小传入setChunkedStreamingMode()方法
 *
 *      还有已知大小可以将大小传递给setFixedLengthStreamingMode(int/long count);不能和分块一块使用
 *
 *
 * @Auther: gjt
 * @Date: 2024/4/7 5:20
 */
public class HttpURLConnections {


    /**
     * 利用get 也可以获得相同的结果,但是会把整个文件发送
     */
    public static void head(String url){
        try{
            URL url1 = new URL(url);
            HttpURLConnection http = (HttpURLConnection)url1.openConnection();
            http.setRequestMethod("HEAD");
//            http.setRequestMethod("GET");
            System.out.println( url1+ "was last modified at" + new Date(http.getLastModified()));

            System.out.println("响应码" + http.getResponseCode());

            System.out.println("响应消息" + http.getResponseMessage());

            // 可以指出某个HttpURLConnection是否通过代理服务器
            http.usingProxy();

            // http1.1 是一个持久连接，在关闭之前可以发送多个tcpSocket 请求 ；这个方法使客户端和服务器断开连接
            http.disconnect();


        }catch (IOException e){
            e.printStackTrace();
        }

    }


    public static void getSource(String url){
        try{
            URL url1 = new URL(url);
            HttpURLConnection http = (HttpURLConnection)url1.openConnection();
            http.setRequestMethod("GET");

            int responseCode = http.getResponseCode();
            String responseMessage = http.getResponseMessage();
            System.out.println("HTTP/1.x "  + responseCode + " " + responseMessage);

            String header = http.getHeaderField(0);
            String key = http.getHeaderFieldKey(0);
            System.out.println(key + ": " + header);
            System.out.println();

            for(int i = 1; ; i++){
                String headerField = http.getHeaderField(i);
                String headerFieldKey = http.getHeaderFieldKey(i);
                if(headerField == null || headerFieldKey == null) break;
                System.out.println(headerFieldKey + ": " + headerField);
            }
            System.out.println();

            try(InputStream in = new BufferedInputStream(http.getInputStream())){
                int available = in.available();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                char[] list = new char[available];
                int start = 0;

                while(start < available){
                    start += reader.read(list,start,available - start);
                    System.out.println(list);
                    if(start == -1)break;
                }
            }catch (IOException e){
                printFormStream(http.getInputStream());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }


    /**
     *  有可能读取时会返回错误的页面（即会返回流）
     */
    private static void printFormStream(InputStream inputStream){
        try(InputStream in = new BufferedInputStream(inputStream)){
            int available = in.available();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            char[] list = new char[available];
            int start = 0;

            while(start < available){
                start += reader.read(list,start,available - start);
                System.out.println(list);
                if(start == -1)break;
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
//        head("http://www.ibiblio.org/xml/");
        getSource("http://gjt1314.xyz");
    }
}
